Перейти к основному содержимому

5.05. Работа с сетью

Разработчику Архитектору

Работа с сетью

Протоколы TCP и UDP

Протоколы TCP и UDP в C#

HTTP и HTTPS

Методы: GET, POST, PUT, DELETE в C#
Заголовки, MIME-типы в C#
Статус-коды в C#
HttpClient: лучший выбор
WebRequest / WebResponse: устаревшие
WebClient: deprecated
Управление HttpClient (реиспользование, IHttpClientFactory)

HTTP (HyperText Transfer Protocol) — протокол прикладного уровня для передачи данных. Мы его изучали и в первом томе, и будем возвращаться в третьем. И C#, как серверный язык, неизбежно связан с HTTP в том числе - на практике придётся сталкиваться с различными задачами, особенно при интеграциях - получение данных (например, список пользователей), отправлять данные, загружать файлы, авторизовываться.

В ранних версиях .NET Framework использовались первые низкоуровневые классы для HTTP-запросов - HttpWebRequest и HttpWebResponse. Сейчас в .NET уже используется - HttpClient, из пространства имён System.Net.Http.

В C# с HTTP можно делать всё что позволяет этот протокол.

Самый простой пример - отправка GET-запроса для получения данных с сервера:

using var client = new HttpClient();
string response = await client.GetStringAsync("https://api.example.com/data");
Console.WriteLine(response);

Здесь, как можно заметить, используется using - потому что HttpClient реализует IDisposable. В данном случае это простой пример получить ответ как строку.

При работе с интеграциями важно предварительно изучить API, типы данных, примеры ответов и запросов, чтобы не допускать ошибок. А если всё подробно описано, то, как и в других языках, возможностей здесь куча.

Можно добавить обработку статус-кода, проверив, успешен ли запрос - для этого используется HttpResponseMessage:

HttpResponseMessage response = await client.GetAsync("https://api.example.com/data");
if (response.IsSuccessStatusCode)
{
string content = await response.Content.ReadAsStringAsync();
var data = JsonSerializer.Deserialize<DataModel>(content);
}

В данном случае IsSuccessStatusCode - true, если код 2xx (например, 200 OK), а Content - тело ответа, из которого можно прочитать строку, поток, байты и т.д.

Можно отправлять POST-запросы, к примеру, JSON - для этого нужно сериализовать объект в JSON, указать тип контента (application/json), и отправить через PostAsync:

var data = new { Name = "Alice", Age = 25 };
string json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
HttpResponseMessage response = await client.PostAsync("https://api.example.com/users", content);

Поддерживается и работа с заголовками (headers). Это метаинформация запроса, их можно добавлять глобально или для каждого запроса. К примеру:

client.DefaultRequestHeaders.Add("Authorization", "Bearer token123");
client.DefaultRequestHeaders.UserAgent.ParseAdd("MyApp/1.0");

Чтение заголовков ответа:

var response = await client.GetAsync("https://api.example.com");
foreach (var header in response.Headers)
{
Console.WriteLine($"{header.Key}: {string.Join(", ", header.Value)}");
}

Query Parameters (параметры запроса) позволяют вручную формировать URL, передавая параметры в URL (?page=1&limit=10). Тут два варианта. Вручную:

string url = "https://api.example.com/users?page=1&limit=10";

Или используя HttpUtility:

var query = HttpUtility.ParseQueryString(string.Empty);
query["page"] = "1";
query["limit"] = "10";
string url = $"https://api.example.com/users?{query}";

HttpUtility находится в System.Web (для .NET Framework) или в пакете System.Web.Extensions (для .NET Core+).

Для загрузки файлов используется multipart/form-data. Пример:

using var content = new MultipartFormDataContent();
content.Add(new StreamContent(File.OpenRead("photo.jpg")), "file", "photo.jpg");
content.Add(new StringContent("123"), "userId");
var response = await client.PostAsync("https://api.example.com/upload", content);

Если нужно отправить PDF, изображение и т.п., используется отправка бинарных данных. ByteArrayContent — для любых бинарных данных. :

byte[] fileBytes = File.ReadAllBytes("document.pdf");
var byteContent = new ByteArrayContent(fileBytes);
byteContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/pdf");
await client.PostAsync("https://api.example.com/upload", byteContent);

Для авторизации можно использовать несколько вариантов:

  1. Basic Auth:
var authToken = Convert.ToBase64String(Encoding.UTF8.GetBytes("user:password"));
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authToken);
  1. Bearer Token (OAuth 2.0):
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "token123");
  1. OAuth 2.0 с HttpClientFactory:
services.AddHttpClient("SecureApi")
.AddHttpMessageHandler(() => new BearerTokenHandler("token123"));

В C# для работы с HTTP-запросами используется набор классов из пространства имен System.Net.Http. Они предоставляют гибкий и мощный API для выполнения HTTP-запросов, обработки ответов и управления соединениями.

HttpClient для отправки запросов и получения ответов. Имеет:

  • GetAsync, PostAsync, PutAsync, DeleteAsync — асинхронные методы для разных HTTP-методов;
  • SendAsync — универсальный метод для отправки кастомных запросов (HttpRequestMessage);
  • GetStringAsync, GetStreamAsync, GetByteArrayAsync — упрощённые методы для получения данных.

Важные свойства:

  • BaseAddress — базовый URL для относительных путей.
  • DefaultRequestHeaders — заголовки, отправляемые с каждым запросом.
  • Timeout — максимальное время ожидания ответа.

HttpClientHandler используется для настройки поведения HTTP-клиента, контролирует низкоуровневые аспекты HTTP-соединений (прокси, SSL, куки и прочее).

HttpMethod — представление HTTP-метода (GET, POST и др.), описывает тип запроса:

  • HttpMethod.Get;
  • HttpMethod.Post;
  • HttpMethod.Put;
  • HttpMethod.Delete;
  • HttpMethod.Patch (появился в .NET 5+).

HttpContent — абстрактный класс для тела запроса/ответа. Представляет содержимое HTTP-сообщения (тело запроса или ответа). У него есть наследники:

  • StringContent — текст (JSON, XML, plain text);
  • ByteArrayContent — бинарные данные (файлы, изображения);
  • MultipartFormDataContent — отправка форм с файлами;
  • StreamContent — потоковые данные.

HttpRequestMessage — настройка запроса. Полная кастомизация HTTP-запроса (метод, URL, заголовки, тело).

HttpResponseMessage — обработка ответа. Содержит данные HTTP-ответа (статус, заголовки, тело).

Основные свойства:

  • StatusCode — код ответа (200 OK, 404 Not Found и т. д.).
  • IsSuccessStatusCode — true, если статус 2xx.
  • Headers — заголовки ответа.
  • Content — тело ответа (HttpContent).

HttpMessageHandler и цепочки обработчиков позволяют встраивать middleware-логику (логирование, аутентификацию).

IHttpClientFactory — фабрика для управления HttpClient. HttpClient реализует IDisposable, но его не следует создавать и уничтожать часто (риск исчерпания сокетов). Это управление жизненным циклом HttpClient.

Отправка email

SmtpClient (устарел), современные альтернативы
Настройка SMTP, порты, TLS

Прокси-сервер

Что такое, зачем нужен
Настройка прокси в .NET